package com.hcc.flow.server.controller.sys;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hcc.flow.server.annotation.LogAnnotation;
import com.hcc.flow.server.annotation.Original;
import com.hcc.flow.server.common.constant.Constant;
import com.hcc.flow.server.common.enums.DataStatusType;
import com.hcc.flow.server.common.model.ApiResult;
import com.hcc.flow.server.common.page.table.PageTableHandler;
import com.hcc.flow.server.common.page.table.PageTableRequest;
import com.hcc.flow.server.common.page.table.PageTableResponse;
import com.hcc.flow.server.common.utils.AssembleUtil;
import com.hcc.flow.server.common.utils.CommUtil;
import com.hcc.flow.server.common.utils.PasswordUtil;
import com.hcc.flow.server.common.utils.StringUtilsV2;
import com.hcc.flow.server.common.vo.SelectRelationVO;
import com.hcc.flow.server.common.vo.SelectVO;
import com.hcc.flow.server.dao.sys.AreaDao;
import com.hcc.flow.server.dao.sys.RoleDao;
import com.hcc.flow.server.dao.sys.UserDao;
import com.hcc.flow.server.dto.sys.ChangePasswordDto;
import com.hcc.flow.server.dto.sys.UserDto;
import com.hcc.flow.server.model.common.LoginUser;
import com.hcc.flow.server.model.sys.SysUser;
import com.hcc.flow.server.service.sys.OrgService;
import com.hcc.flow.server.service.sys.RedisServer;
import com.hcc.flow.server.service.sys.UserService;
import com.hcc.flow.server.utils.CheckIdUtil;
import com.hcc.flow.server.utils.UserUtil;
import com.hcc.flow.server.vo.sys.OrgOneVO;
import com.hcc.flow.server.vo.sys.SysUserDetailVO;
import com.hcc.flow.server.vo.sys.SysUserVO;
import com.hcc.flow.server.vo.sys.UserShortInfoVO;
import com.hcc.flow.server.where.sys.SysUserWhere;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 用户相关接口
 * 
 * @author 韩长长 
 *
 */
@Api(tags = "用户")
@RestController
@RequestMapping("/users")
public class UserController {

	private static final Logger log = LoggerFactory.getLogger("adminLogger");

	@Autowired
	private UserService userService;
	@Autowired
	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private OrgService orgService;
	@Autowired
	private AreaDao areaDao;

	@LogAnnotation
	@PostMapping
	@ApiOperation(value = "用户-保存")
	//@PreAuthorize("hasAuthority('sys:user:add')")
	public ApiResult<?> saveUser(@RequestBody UserDto userDto) {
		if (userDto == null) {
			return ApiResult.error("用户数据不能为空");
		} else if (StringUtilsV2.isBlank(userDto.getUserAcct())) {
			return ApiResult.error("用户账号不能为空");
		}
		SysUser localUser = userService.getUser(userDto.getUserAcct());
		if (localUser != null) {
			return ApiResult.error("用户名：" + userDto.getUserAcct() + "已存在");
		}
		if (StringUtilsV2.isNotBlank(userDto.getPhone())) {
			localUser = userDao.getUserByPhone(userDto.getPhone());
			if (localUser != null) {
				return ApiResult.error("手机号：" + userDto.getPhone() + "已存在");
			}
		}
		if (StringUtilsV2.isNotBlank(userDto.getEmail())) {
			localUser = userDao.getUserByEmail(userDto.getEmail());
			if (localUser != null) {
				return ApiResult.error("邮箱：" + userDto.getEmail() + "已存在");
			}
		}
		String password = userService.saveUser(userDto);
		return ApiResult.data(password);
	}

	@PostMapping("/loginReg")
	@ApiOperation(value = "用户-自注册")
	public ApiResult<?> loginReg(@RequestBody UserDto userDto) {
		if (userDto == null) {
			return ApiResult.error("用户数据不能为空");
		} 
		if (StringUtilsV2.isBlank(userDto.getUserAcct())) {
			return ApiResult.error("用户账号不能为空");
		}
		if (StringUtilsV2.isBlank(userDto.getPassword())) {
			return ApiResult.error("用户密码不能为空");
		}
		if (StringUtilsV2.isBlank(userDto.getVerifyIdR()) || StringUtilsV2.isBlank(userDto.getVerifyCodeR())) {
			return ApiResult.error("验证码不能为空");
		}
		String strRes = ValidateCode(userDto.getVerifyIdR(),userDto.getVerifyCodeR());
		if (!"1".equals(strRes)) {
			return ApiResult.error(strRes);
		}
		SysUser localUser = userService.getUser(userDto.getUserAcct());
		if (localUser != null) {
			return ApiResult.error("用户名：" + userDto.getUserAcct() + "已存在,可直接登录");
		}
		if (StringUtilsV2.isNotBlank(userDto.getPhone())) {
			localUser = userDao.getUserByPhone(userDto.getPhone());
			if (localUser != null) {
				return ApiResult.error("手机号：" + userDto.getPhone() + "已存在,可直接登录");
			}
		}
		if (StringUtilsV2.isNotBlank(userDto.getEmail())) {
			localUser = userDao.getUserByEmail(userDto.getEmail());
			if (localUser != null) {
				return ApiResult.error("邮箱：" + userDto.getEmail() + "已存在");
			}
		}
		userDto.setRoleIds(Arrays.asList("3"));
		userDto.setOrgId("2");
		String password = userService.saveUser(userDto);
		return ApiResult.data(password);
	}
	@LogAnnotation
	@PutMapping
	@ApiOperation(value = "用户-修改")
	//@PreAuthorize("hasAuthority('sys:user:add')")
	public ApiResult<?> updateUser(@RequestBody UserDto userDto) {
		if (userDto == null) {
			return ApiResult.error("用户数据不能为空");
		}
		if (StringUtilsV2.isBlank(userDto.getUserId())) {
			return ApiResult.error("要修改的用户ID不能为空");
		}
		SysUser localUser = null;
		if (StringUtilsV2.isNotBlank(userDto.getUserAcct())) {
			localUser = userService.getUser(userDto.getUserAcct());
			if (localUser != null && !userDto.getUserId().equals(localUser.getUserId())) {
				return ApiResult.error("用户名：" + userDto.getUserAcct() + "已存在");
			}
		}
		if (StringUtilsV2.isNotBlank(userDto.getPhone())) {
			localUser = userDao.getUserByPhone(userDto.getPhone());
			if (localUser != null && !userDto.getUserId().equals(localUser.getUserId())) {
				return ApiResult.error("手机号：" + userDto.getPhone() + "已存在");
			}
		}
		if (StringUtilsV2.isNotBlank(userDto.getEmail())) {
			localUser = userDao.getUserByEmail(userDto.getEmail());
			if (localUser != null && !userDto.getUserId().equals(localUser.getUserId())) {
				return ApiResult.error("邮箱：" + userDto.getEmail() + "已存在");
			}
		}
		if ("R".equals(userDto.getStatus()) && (userDto.getUserId().equals("1") || userDto.getUserId().equals("10"))) {
			return ApiResult.error("操作错误:系统全局管理员admin状态不能修改");
		}
		ApiResult<?> checkAr = CheckIdUtil.checkId(Arrays.asList("1","10"), userDto.getUserId());
		if(!checkAr.isSuccess()){
			return checkAr;
		}
		userService.updateUser(userDto);
		return ApiResult.ok();
	}

	@LogAnnotation
	@PutMapping(params = "headImgUrl")
	@ApiOperation(value = "用户-修改头像")
	public ApiResult<?> updateHeadImgUrl(String headImgUrl) {
		LoginUser user = UserUtil.getLoginUser();
		UserDto userDto = new UserDto();
		BeanUtils.copyProperties(user, userDto);
		userDto.setHeadImgUrl(headImgUrl);

		userService.updateUser(userDto);
		log.debug("{}修改了头像", user.getUserAcct());
		return ApiResult.ok();
	}

	@LogAnnotation
	@PutMapping("/changePassword")
	@ApiOperation(value = "用户-修改密码")
	// //@PreAuthorize("hasAuthority('sys:user:password')")
	public ApiResult<?> changePassword(@RequestBody ChangePasswordDto dto) {
		return userService.changePassword(dto);
	}

	@LogAnnotation
	@GetMapping("/resetPassword/{id}")
	@ApiOperation(value = "用户-重置密码")
	// //@PreAuthorize("hasAuthority('sys:user:password')")
	public ApiResult<?> resetPassword(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("用户id不能为空");
		}
		SysUser user = userDao.getById(id);
		if (user == null) {
			return ApiResult.error("用户不存在");
		}
		ApiResult<?> checkAr = CheckIdUtil.checkId(Arrays.asList("1","10"), id);
		if(!checkAr.isSuccess()){
			return checkAr;
		}
		String password = PasswordUtil.randomPassword();
		return userService.changePasswordReset(id, password);
	}

	@ApiOperation(value = "用户-当前登录用户")
	@GetMapping("/current")
	public SysUser currentUser() {
		return UserUtil.getLoginUser();
	}

	@ApiOperation(value = "用户-根据用户id获取用户")
	@GetMapping("/{id}")
	/* //@PreAuthorize("hasAuthority('sys:user:query')") */
	public ApiResult<?> user(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("要查询的id不能为空");
		}
		SysUserDetailVO vo = userDao.getById(id);
		if (vo != null) {
			vo.setRoleIds(roleDao.listIdsByUserId(id));
		}
		return ApiResult.data(vo);
	}

	@ApiOperation(value = "用户-当前登录用户简单信息")
	@GetMapping("/currentshort")
	public UserShortInfoVO currentShortUser() {
		LoginUser user = UserUtil.getLoginUser();
		UserShortInfoVO userInfo = userDao.getShortUser(user.getUserAcct());
		OrgOneVO org = orgService.getOne(user.getOrgId(), null);
		if (org != null) {
			userInfo.setWebLoginLogoAll(org.getWebLoginLogoAll());
			userInfo.setWebLogoAll(org.getWebLogoAll());
			userInfo.setWebTitle(org.getWebTitle());
		} else {
			userInfo.setWebLoginLogoAll(Constant.PLATFORM_WEB_LOGIN_LOGO);
			userInfo.setWebLogoAll(Constant.PLATFORM_WEB_LOGO);
			userInfo.setWebTitle(Constant.PLATFORM_WEB_TITLE);
		}
		String orgName = org.getOrgName();
		if (orgName != null) {
			// orgName = orgName.replace(oldChar, "");
			// String o = "重庆hcc-flow数字技术有限公司";
			// System.out.println(o.replaceAll("(?:省|市|有限公司|重庆)", ""));
			StringBuffer sb = new StringBuffer("(?:省").append("|市").append("|区").append("|县").append("|自治州")
					.append("|有限公司");
			sb.append("|").append(areaDao.getNamesByType12()).append(")");
			orgName = orgName.replaceAll(sb.toString(), "");
			if (orgName.length() > 6) {
				orgName = orgName.substring(0, 6) + "..";
			}
			userInfo.setUserName(orgName + "<br/>" + userInfo.getUserName());
		}
		return userInfo;
	}

	@PostMapping("/list")
	@ApiOperation(value = "用户-列表（分页）")
	//@PreAuthorize("hasAuthority('sys:user:query') or hasAuthority('customer:customer:query')")
	public PageInfo<SysUserVO> ListNew(@RequestBody SysUserWhere strCon) {
		PageHelper.startPage(strCon.getOffset(), strCon.getLimit());
		if (StringUtilsV2.isBlank(strCon.getSqlOrder())) {
			strCon.setSqlOrder("t.create_time desc ");
		}
		String status = strCon.getStatus();
		if (StringUtilsV2.isNotBlank(status)) {
			List<String> statuss = strCon.getStatuss();
			if (statuss == null) {
				statuss = new ArrayList<>();
			}
			statuss.add(status);
			strCon.setStatuss(statuss);
		}
		PageHelper.orderBy(strCon.getSqlOrder());
		List<SysUserVO> list = userDao.SysUserList(strCon);
		PageInfo<SysUserVO> result = new PageInfo<SysUserVO>(list);
		return result;
	}

	@GetMapping
	@ApiOperation(value = "用户列表-工作流专用")
	//@PreAuthorize("hasAuthority('sys:msgNoticeRead:query')")
	@Original
	public PageTableResponse LogListNew(PageTableRequest strCon) {
		SysUserWhere where = new SysUserWhere(strCon);
		// userService.setOrgIdAndRoleIds(where,"sys:user:query");
		PageHelper.startPage(where.getOffset(), where.getLimit());
		if (StringUtilsV2.isBlank(where.getSqlOrder())) {
			where.setSqlOrder("t.create_time desc");
		}
		PageHelper.orderBy(where.getSqlOrder());
		List<SysUserVO> list = userDao.SysUserList(where);
		PageInfo<SysUserVO> result = new PageInfo<SysUserVO>(list);
		return new PageTableHandler(new PageTableHandler.CountHandler() {
			@Override
			public int count(PageTableRequest request) {
				return CommUtil.null2Int(result.getTotal());
			}
		}, new PageTableHandler.ListHandler() {
			@Override
			public List<SysUserVO> list(PageTableRequest request) {
				return result.getList();
			}
		}).handle(strCon);
		// return PageInfo<SysLogs> list = sysLogService.findAllLogs(new
		// LogWhere(strCon));
	}

	@PostMapping("/list/flow")
	@ApiOperation(value = "用户列表-工作流专用（分页）")
	//@PreAuthorize("hasAuthority('sys:msgNoticeRead:query')")
	public PageInfo<SysUserVO> ListNewF(@RequestBody SysUserWhere strCon) {
		PageHelper.startPage(strCon.getOffset(), strCon.getLimit());
		if (StringUtilsV2.isBlank(strCon.getSqlOrder())) {
			strCon.setSqlOrder("t.create_time desc ");
		}
		String status = strCon.getStatus();
		if (StringUtilsV2.isNotBlank(status)) {
			List<String> statuss = strCon.getStatuss();
			if (statuss == null) {
				statuss = new ArrayList<>();
			}
			statuss.add(status);
			strCon.setStatuss(statuss);
		}
		PageHelper.orderBy(strCon.getSqlOrder());
		List<SysUserVO> list = userDao.SysUserList(strCon);
		PageInfo<SysUserVO> result = new PageInfo<SysUserVO>(list);
		return result;
	}

	@LogAnnotation
	@DeleteMapping("/delete/{id}")
	@ApiOperation(value = "用户-物理删除")
	//@PreAuthorize("hasAuthority('sys:user:del')")
	public ApiResult<?> delete(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("ID不能为空");
		}
		LoginUser user = UserUtil.getLoginUser();
		if (id.equals(user.getUserId())) {
			return ApiResult.error("操作错误:自己不能删除自己");
		}
		if (id.equals("1") || id.equals("10")) {
			return ApiResult.error("操作错误:系统全局管理员admin不能被删除");
		}
		ApiResult<?> checkAr = CheckIdUtil.checkId(Arrays.asList("1","10"), id);
		if(!checkAr.isSuccess()){
			return checkAr;
		}
		userDao.delete(id);
		userDao.deleteUserRole(id);
		return ApiResult.ok();
	}

	@LogAnnotation
	@DeleteMapping("/{id}")
	@ApiOperation(value = "用户-停用")
	//@PreAuthorize("hasAuthority('sys:user:stop')")
	public ApiResult<?> stop(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("ID不能为空");
		}
		LoginUser user = UserUtil.getLoginUser();
		if (id.equals(user.getUserId())) {
			return ApiResult.error("操作错误:自己不能停用自己");
		}
		if (id.equals("1") || id.equals("10")) {
			return ApiResult.error("操作错误:系统全局管理员admin不能被停用");
		}
		ApiResult<?> checkAr = CheckIdUtil.checkId(Arrays.asList("1","10"), id);
		if(!checkAr.isSuccess()){
			return checkAr;
		}
		userDao.updateStatus(Arrays.asList(id), DataStatusType.STOP.getCode());
		return ApiResult.ok();
	}

	@LogAnnotation
	@DeleteMapping("/del/{id}")
	@ApiOperation(value = "用户-逻辑删除")
	//@PreAuthorize("hasAuthority('sys:user:del')")
	public ApiResult<?> deleteEditStatus(@PathVariable String id) {
		if (StringUtilsV2.isBlank(id)) {
			return ApiResult.error("ID不能为空");
		}
		LoginUser user = UserUtil.getLoginUser();
		if (id.equals(user.getUserId())) {
			return ApiResult.error("操作错误:自己不能删除自己");
		}
		if (id.equals("1") || id.equals("10")) {
			return ApiResult.error("操作错误:系统全局管理员admin不能被删除");
		}
		ApiResult<?> checkAr = CheckIdUtil.checkId(Arrays.asList("1","10"), id);
		if(!checkAr.isSuccess()){
			return checkAr;
		}
		userDao.updateStatus(Arrays.asList(id), DataStatusType.DELETE.getCode());
		return ApiResult.ok();
	}

	@GetMapping("/listValidSelect/{type}")
	@ApiOperation(value = "有效搜索条件")
	public Map<String, Object> listValidSelect(@PathVariable String type) {
		Map<String, Object> map = new HashMap<>();
		map.put("listValidOrg", new ArrayList<SelectVO>());
		map.put("listValidDep", new ArrayList<SelectRelationVO>());
		map.put("listValidStatus", DataStatusType.selectVOsNORMAL());

		return map;
	}

	@LogAnnotation
	@GetMapping("/clearRedis")
	@ApiOperation(value = "手动清空redis中缓存数据")
	public ApiResult<?> clearRedis() {
		return ApiResult.ok();
	}

	@PostMapping("/role")
	@ApiOperation(value = "角色-根据角色ids获取角色下面所有用户")
	// //@PreAuthorize("hasAuthority('sys:role:query')")
	public ApiResult<?> getRolesByOrgIds(@RequestBody List<String> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return ApiResult.error("要查询的roleIds不能为空");
		}
		return ApiResult.data(AssembleUtil.selectCheck(userDao.getSelectRelationVOByRoleIds(StringUtilsV2.join(ids, ","))));
	}
	
	public String ValidateCode(String verifyId,String verifyCode) {
		String strRes = "1";
		try {
			if (StringUtilsV2.isBlank(verifyId)) {
				strRes = "传入验证码ID为空";
			}
			Object captchaValue = RedisServer.getCacheValue("login-code", verifyId);
			if (captchaValue == null || StringUtilsV2.isBlank(captchaValue.toString())) {
				strRes = "验证码已过期";
			} else {
				if (!captchaValue.toString().equalsIgnoreCase(verifyCode)) {
					strRes = "验证码错误";
				} else {
					RedisServer.remove("login-code", verifyId);
				}
			}
		} catch (Exception e) {
			strRes = "异常错误：" + e.getMessage();
		}
		return strRes;
	}
}
